﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using T.ServiceFramework.Spi;
using T.ServiceComponent.Cluster.Client;
using T.ServiceComponent.Cluster.SPI;
using T.ServiceComponent.Error;

namespace T.SF.Console
{
    internal class ClusterService
    {
        /// <summary>
        /// 获取本机的IP列表
        /// </summary>
        /// <returns></returns>
        private static List<string> GetHostIPs()
        {
            string hostName = Dns.GetHostName();//本机名   
            System.Net.IPAddress[] addressList = Dns.GetHostAddresses(hostName);//会返回所有地址，包括IPv4和IPv6   
            List<string> result = new List<string>();
            foreach (IPAddress ip in addressList)
            {
                result.Add(ip.ToString());
            }
            result.Add("127.0.0.1");
            result.Add("localhost");
            return result;
        }

        public static AppHost GetMyHostInfo()
        {
            if (AppConfig.IsLocalModel())
            {
                AppHost appHost = GetHostInfoFromLocal();
                TSFLogger.Info($"Run as LocalModel,  HostID:{appHost.ID}, ClusterID:{appHost.ClusterID}");
                return appHost;
            }
            var hostID = AppConfig.GetHostID();
            ApplicationHost cmdbHost = null;
            if (string.IsNullOrEmpty(hostID))
            {
                throw new TException(SFErrorCode.InvalideParam, "Unable to get the current Host information.");
            }
            else
            {
                cmdbHost = AppClusterQueryClient.Current.GetAppHost(hostID);
                if (cmdbHost == null)
                    throw new TException(SFErrorCode.InvalideParam, "The system did not get valid Application host information.HostID：" + hostID);
            }

            var host = new AppHost() { ID = cmdbHost.ID, AppNodeID = cmdbHost.ApplicationNodeID, ClusterID = cmdbHost.ClusterID, Code = cmdbHost.Code, CreateBy = cmdbHost.Creator, CreateTime = cmdbHost.CreateTime, IsEnable = cmdbHost.IsEnable, LastModifyBy = cmdbHost.LastModifier, LastModifyTime = cmdbHost.LastModifyTime, Name = cmdbHost.Name };
            host.BindingList = new List<Binding>();
            var bindList = AppClusterQueryClient.Current.GetAppHostBindingListByHostID(cmdbHost.ID);
            if (bindList != null)
            {
                string bindConfig = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config", "bindinglist.json"));
                var localBindingListConfig = JsonConvert.DeserializeObject<List<Binding>>(bindConfig);
                //完全基于BindList，作为后续三类元数据加载的依据，不再强制绑定HSF、SG，以区分仅加载MAC元数据的情况，同时避免仅绑定MAC时仍按照Host中Port绑定HSF和固定端口绑定SG导致的端口复用异常
                bindList.ForEach(x =>
                {
                    var binding = localBindingListConfig.FirstOrDefault(b => string.Equals(b.ServiceType.ToString(), x.ServiceType, StringComparison.OrdinalIgnoreCase));
                    if (binding != null)
                    {
                        binding.IP = x.HostIPAddress;
                        binding.Port = x.Port;
                    }

                    host.BindingList.Add(binding);
                });
            }

            host.ClusterTypeList = AppClusterQueryClient.Current.GetAppClusterTypesByHostID(cmdbHost.ID);

            return host;
        }

        internal static AppHost GetHostInfoFromLocal()
        {
            AppHost appHost = new AppHost() { IsLocalModel = true };
            appHost.ID = AppConfig.GetHostID();
            appHost.ClusterID = T.ServiceComponent.Kernel.Service.ConfigHelper.GetString("ClusterID");

            string bindConfig = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config", "bindinglist.json"));
            appHost.BindingList = JsonConvert.DeserializeObject<List<Binding>>(bindConfig);
            appHost.ClusterTypeList = T.ServiceComponent.Kernel.Service.ConfigHelper.GetString("ClusterTypeList").Split(',').ToList();
            return appHost;
        }
    }
}
